<?php

require_once(BaseConfig::LoadClass('objeto_base.class.php'  ));
require_once(BaseConfig::LoadClass('configuracion.class.php'));
require_once(BaseConfig::LoadClass('filtro.class.php'       ));
require_once(BaseConfig::LoadClass('paginador.class.php'    ));

/**
 * Clase que maneja a los usuarios
 */
class Usuario extends ObjetoBase {
  var $intIdUsuario;
  var $strNombre;
  var $strNick;
  var $strPass;
  var $strTipo;
  var $strIpsPosibles;
  var $strIpsNegadas;
  var $intStatus;
  var $dteLastLog;
  var $dteLastChangePass;

  /**
   * Constructor. Si se pasa el parametro (Y existe el usuario con ese ID) el objeto se llenará
   * 
   * @param int $intIdUsuario
   */
  function Usuario($intIdUsuario = 0) {
    $arrMapaDatos = Array();
    $arrMapaDatos['id_usuario'      ] = Array('NombreVariable' => 'intIdUsuario'     , 'TipoVariable' => 'I');
    $arrMapaDatos['nombre'          ] = Array('NombreVariable' => 'strNombre'        , 'TipoVariable' => 'S');
    $arrMapaDatos['nick'            ] = Array('NombreVariable' => 'strNick'          , 'TipoVariable' => 'S');
//    $arrMapaDatos['pass'            ] = Array('NombreVariable' => 'strPass'          , 'TipoVariable' => 'S');
    $arrMapaDatos['tipo'            ] = Array('NombreVariable' => 'strTipo'          , 'TipoVariable' => 'S');
    $arrMapaDatos['ips_posibles'    ] = Array('NombreVariable' => 'strIpsPosibles'   , 'TipoVariable' => 'S');
    $arrMapaDatos['ips_negadas'     ] = Array('NombreVariable' => 'strIpsNegadas'    , 'TipoVariable' => 'S');
    $arrMapaDatos['status'          ] = Array('NombreVariable' => 'intStatus'        , 'TipoVariable' => 'N');
    $arrMapaDatos['last_log'        ] = Array('NombreVariable' => 'dteLastLog'       , 'TipoVariable' => 'D');
    $arrMapaDatos['last_change_pass'] = Array('NombreVariable' => 'dteLastChangePass', 'TipoVariable' => 'D');
    
    $this->__ArmarDatosPrivados('usuarios', $arrMapaDatos, 'id_usuario');
    $this->SeleccionarPorIndice($intIdUsuario);
  }

  /**
   * Función que llena los objetos extra. Se implementa aqui para que si se 
   * necesita aumentar la clase no se olvde de cambiarse esta parte
   */
  function ObtenerObjetos() {
  }

  /**
   * Función que obtiene todos los datos de un usuario, incluyendo la fecha de
   * ultimo logueo y la fecha de ultimo cambio de password, y llena $this con
   * esa información.
   *
   * @param int $intIdUsuario Usuario que se buscará
   */
  function SeleccionarPorIndiceA($intIdUsuario) {
    $this->__arrMapaDatos  ['last_log'] = 'dteLastLog';
    $this->__arrMapaNombres['last_log'] = 'last_log';
    $this->__arrMapaTipos  ['last_log'] = 'D';
    
    $this->__arrMapaDatos  ['last_change_pass'] = 'dteLastChangePass';
    $this->__arrMapaNombres['last_change_pass'] = 'last_change_pass';
    $this->__arrMapaTipos  ['last_change_pass'] = 'D';
    
    parent::SeleccionarPorIndice($intIdUsuario);
    
    unset($this->__arrMapaDatos  ['last_log']);
    unset($this->__arrMapaNombres['last_log']);
    unset($this->__arrMapaTipos  ['last_log']);
    
    unset($this->__arrMapaDatos  ['last_change_pass']);
    unset($this->__arrMapaNombres['last_change_pass']);
    unset($this->__arrMapaTipos  ['last_change_pass']);
  }

  /**
   * Función que obtiene las IP's desde las cuales un usuario se puede loguear.
   *
   * @return Array Arreglo conlas IP's desde las cuales este usuario se puede loguear
   */
  function ArrayIpsPosibles() {
    $arrTmp = explode(',', $this->strIpsPosibles);
    $arrRet = Array();
    foreach($arrTmp as $strIp) {
      $strIp = Variables::IpNormal(trim($strIp));
      if($strIp) {
        $arrRet[] = $strIp;
      }
    }

    return $arrRet;
  }

  /**
   * Función que obtiene las IP's desde las cuales un usuario NO se puede loguear.
   *
   * @return Array Arreglo conlas IP's desde las cuales este usuario NO se puede loguear
   */
  function ArrayIpsNegadas() {
    $arrTmp = explode(',', $this->strIpsNegadas);
    $arrRet = Array();
    foreach($arrTmp as $strIp) {
      $strIp = Variables::IpNormal(trim($strIp));
      if($strIp) {
        $arrRet[] = $strIp;
      }
    }

    return $arrRet;
  }

  /**
   * Función para guardar al usuario. Si es un usuario nuevo tambien se guardará el password
   *
   * @return String Consulta usada para guardar al usuario
   */
  function  GuardarObjeto($bolHacerLlamada = true, $bolObtenerIdCreado = false, $bolGenerarIndice = false) {
    $strConsulta = '';
    if(!$this->intIdUsuario) {
      // Se creará al usuario, por lo qu se debe colocar el password tambien
      $this->__arrMapaNombres['pass'] = 'pass';
      $this->__arrMapaDatos  ['pass'] = 'strPass';
      $this->__arrMapaTipos  ['pass'] = 'S';
      $this->strPass = md5($this->strPass);
      $strConsulta = parent::GuardarObjeto($bolHacerLlamada, $bolObtenerIdCreado, $bolGenerarIndice);
      unset($this->__arrMapaNombres['pass']);
      unset($this->__arrMapaDatos  ['pass']);
      unset($this->__arrMapaTipos  ['pass']);
    } else {
      $strConsulta = parent::GuardarObjeto($bolHacerLlamada, $bolObtenerIdCreado, $bolGenerarIndice);
    }

    return $strConsulta;
  }
  
  /**
   * Cambiar solo el password de un usuario existente
   *
   * @return String Consulta usada para cambiar el password del usuario
   */
  function CambiarPass() {
    if($this->intIdUsuario - 0) {
      $oConecta = new Conecta();
      $strConsulta = 'UPDATE usuarios SET pass = \'' . md5($this->strPass) . '\', last_change_pass = NOW() WHERE id_usuario = ' . ($this->intIdUsuario - 0);
      $oConecta->Consulta($strConsulta);
      
      return $strConsulta;
    }
  }

  /**
   * Cambiar solo la fecha de ultimo logueo
   *
   * @return String Consulta usada para cambiar la fecha de ultimo logueo del usuario
   */
  function CambiarLastLog() {
    if($this->intIdUsuario - 0) {
      $oConecta = new Conecta();
      $strConsulta = 'UPDATE usuarios SET last_log = NOW() WHERE id_usuario = ' . ($this->intIdUsuario - 0);
      $oConecta->Consulta($strConsulta);
      return $strConsulta;
    }
  }

  /**
   * Función que obtiene una cadena con la descripción de cuanto tiempo falta
   * para que el usuario tenga que cambiar su password o tenga que ser
   * deshabilitado.
   *
   * @return String Descripción, o cadena vacia si el usuario no necesita cambiar su password nunca
   */
  function TiempoFaltanteCambioPass() {
    $oConfiguracion = new Config();
    
    if($oConfiguracion->Get('pass_time_limit', '0') == '0') {
      return '';
    }
    
    $dateDiff    = strtotime($this->dteLastChangePass) - mktime(date('H'), date('i'), date('s'), date('n'), date('j') - $oConfiguracion->Get('pass_time_limit', '0'), date('Y'));
    $fullDays    = floor($dateDiff / (60 * 60 * 24));
    $fullHours   = floor(($dateDiff - ($fullDays * 60 * 60 * 24)) / (60 * 60));
    $fullMinutes = floor(($dateDiff - ($fullDays * 60 * 60 * 24) - ($fullHours * 60 * 60)) / 60);
    return "Faltan $fullDays dias, $fullHours horas y $fullMinutes minutos para cambiar su password";
  }

  /**
   * Función que checa su el usuario con nick $strNick y password (encriptado) $strPass existe
   * 
   * @param String $strNick Nick del usuario
   * @param String $strPass Password del usuario
   *
   * @return int El ID del usuario si la información es correcta, o 0 si no lo es, o un número negativo si no se puede loguear por tener un status deshabilitado
   */
  function ChecarLogin($strNick, $strPass) {
    $oConecta    = new Conecta();
    $strConsulta = 'SELECT id_usuario, pass, status FROM usuarios WHERE nick = \'' . OperacionesDB::CambioValoresNoPosiblesDB($strNick) . '\'';
    $oConecta->Consulta($strConsulta);

    if($oConecta->EOF) {
      return 0;
    }
    
    if($oConecta->Field('status') != 1) {
      return $oConecta->Field('status') * -1;
    }

    if($oConecta->Field('pass') != md5($strPass)) {
      return 0;
    }

    return $oConecta->Field('id_usuario');
  }

  /**
   * Función que deshabilita a los usuarios que tengan más tiempo del permitido sin cambiar su password
   * 
   * @return null
   */
  static function DeshabilitarUsuarios() {
    $oConfig     = new Config();
    $oConecta    = new Conecta();
    
    if($oConfig->Get('pass_time_limit', '0') == '0') {
      return;
    }

    $strConsulta = "UPDATE usuarios SET status = 2 WHERE tipo != 'Admin' AND last_change_pass < '" . date('Y-m-d H:i:s', mktime(date('H'), date('i'), date('s'), date('n'), date('j') - $oConfig->Get('pass_time_limit', '0'), date('Y'))) . "'";
    $oConecta->Consulta($strConsulta);

    return;
  }
  
  static function PaginaEdicion($intPagina = 0) {
    global $oSesion;
    $oTemplate = new Template();
    
    $intPagina -= 0;
    if($intPagina == 0) {
      $intPagina = 1;
    }

    $oFiltroUsuarios = new FiltroUsuarios();
    $oConfiguracion  = new Config();
    
    $oFiltroUsuarios->SetOpcionSalida('usuarios');
    $oFiltroUsuarios->LlenarDatos    ($_POST);

    if($oFiltroUsuarios->__intPaginaDeSesion) {
      $intPagina = $oFiltroUsuarios->__intPaginaDeSesion;
    }

    $arrCarga    = ObjetoBase::Fabrica($oFiltroUsuarios->ObtenerIndices(), 'Usuario');
    $oPaginador  = new Paginador($arrCarga, $intPagina, $oConfiguracion->Get('num_res_pag', '3'));
    $arrUsuarios = $oPaginador->ObtenerArregloActual();

    $strEdUsGeneral = "";
    $strEdUsPerm    = "";
    $strEdUsLogs    = "";
    $strEdUsPass    = "";
    $strEdUsInfo    = "";

    $arrOpcionesUsuario = Permiso::ObtenerPermisosUsuario($oSesion->oUsuario->intIdUsuario);

    $arrOpcionesTipoUsuario['Normal'] = 'Usuario normal';
    $arrOpcionesTipoUsuario['Admin' ] = 'Administrador';

    $arrOpcionesEstatusUsuario[0] = 'Deshabilitado';
    $arrOpcionesEstatusUsuario[1] = 'Activo';
    $arrOpcionesEstatusUsuario[2] = 'Deshabilitado por no cambiar el password';

    $strRowsUsuario = '';

    $strSelectTipoUsuario    = Variables::GetSelectByArray($arrOpcionesTipoUsuario   , '', 'usuario[tipo]'  );
    $strSelectEstatusUsuario = Variables::GetSelectByArray($arrOpcionesEstatusUsuario, '', 'usuario[status]');

    eval('$strRowsUsuario .= "' . $oTemplate->Get('usuario_nuevo.tpl.php') . '";');
    
    foreach($arrUsuarios as $oUsuario) {
      $intIdUsuario     = $oUsuario->intIdUsuario;
      $strNombreUsuario = $oUsuario->strNombre;
      $strNickUsuario   = $oUsuario->strNick;
      $strIpsPosibles   = $oUsuario->strIpsPosibles;
      $strIpsNegadas    = $oUsuario->strIpsNegadas;

      $strEdicionPermisos      = Permiso::ObtenerTemplatePermisos($oUsuario->intIdUsuario);

      $strSelectTipoUsuario    = Variables::GetSelectByArray($arrOpcionesTipoUsuario   , $oUsuario->strTipo          , 'usuario[tipo]'  );
      $strSelectEstatusUsuario = Variables::GetSelectByArray($arrOpcionesEstatusUsuario, $oUsuario->intStatus        , 'usuario[status]');

      eval('$strRowsUsuario    .= "' . $oTemplate->Get('usuario_existente.tpl.php') . '";');
    }

    return $oFiltroUsuarios->GeneraTemplateBusqueda($strRowsUsuario, $oPaginador);
  }
}

class FiltroUsuarios extends Filtro {
  function FiltroUsuarios() {
    $arrProceso["nick"] = "Nombre";
    $arrProceso["tipo"] = "Tipo"  ;
    
    $arrReferencias["tipo"]["datos"]["Normal"] = "Usuario normal";
    $arrReferencias["tipo"]["datos"]["Admin" ] = "Administrador" ;

    parent::CrearFiltro("usuarios", "id_usuario", $arrProceso, "Busqueda", "", "", "Usuarios", $arrReferencias);
  }
}

?>